From 2e18b662f8c13b1bc98426a46999118c84b1c95e Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 29 Jun 2004 14:01:49 +0000 Subject: [PATCH] bitkeeper revision 1.1026.2.1 (40e1764d1ndRTs9hmUyiBLEHi5_V3A) Fix network backend bugs. It isn't safe to use skb->cb[] for our own purposes after all. :-( --- .../arch/xen/drivers/netif/backend/main.c | 74 +++++++++---------- .../arch/xen/drivers/netif/frontend/main.c | 38 +++------- 2 files changed, 45 insertions(+), 67 deletions(-) diff --git a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c index 67de998304..8bdfdbdb1f 100644 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c @@ -28,12 +28,6 @@ static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0); static void net_rx_action(unsigned long unused); static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0); -typedef struct { - u16 id; - unsigned long old_mach_ptr; - unsigned long new_mach_pfn; - netif_t *netif; -} rx_info_t; static struct sk_buff_head rx_queue; static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2]; static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE*3]; @@ -48,8 +42,10 @@ static unsigned long mmap_vstart; #define PKT_PROT_LEN (ETH_HLEN + 20) -static u16 pending_id[MAX_PENDING_REQS]; -static netif_t *pending_netif[MAX_PENDING_REQS]; +static struct { + netif_tx_request_t req; + netif_t *netif; +} pending_tx_info[MAX_PENDING_REQS]; static u16 pending_ring[MAX_PENDING_REQS]; typedef unsigned int PEND_RING_IDX; #define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1)) @@ -61,11 +57,6 @@ static u16 dealloc_ring[MAX_PENDING_REQS]; static spinlock_t dealloc_lock = SPIN_LOCK_UNLOCKED; static PEND_RING_IDX dealloc_prod, dealloc_cons; -typedef struct { - u16 idx; - netif_tx_request_t req; - netif_t *netif; -} tx_info_t; static struct sk_buff_head tx_queue; static multicall_entry_t tx_mcl[MAX_PENDING_REQS]; @@ -127,6 +118,8 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) { netif_t *netif = (netif_t *)dev->priv; + ASSERT(skb->dev == dev); + /* Drop the packet if the target domain has no receive buffers. */ if ( (netif->rx_req_cons == netif->rx->req_prod) || ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) ) @@ -152,15 +145,14 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) skb_reserve(nskb, hlen); __skb_put(nskb, skb->len); (void)skb_copy_bits(skb, -hlen, nskb->head, hlen + skb->len); + nskb->dev = skb->dev; dev_kfree_skb(skb); skb = nskb; } - ((rx_info_t *)&skb->cb[0])->id = - netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_req_cons++)].req.id; - ((rx_info_t *)&skb->cb[0])->netif = netif; - - __skb_queue_tail(&rx_queue, skb); + netif->rx_req_cons++; + + skb_queue_tail(&rx_queue, skb); tasklet_schedule(&net_rx_tasklet); return 0; @@ -195,7 +187,7 @@ static void net_rx_action(unsigned long unused) netif_t *netif; s8 status; u16 size, id, evtchn; - mmu_update_t *mmu = rx_mmu; + mmu_update_t *mmu; multicall_entry_t *mcl; unsigned long vdata, mdata, new_mfn; struct sk_buff_head rxq; @@ -206,9 +198,10 @@ static void net_rx_action(unsigned long unused) skb_queue_head_init(&rxq); mcl = rx_mcl; - while ( (skb = __skb_dequeue(&rx_queue)) != NULL ) + mmu = rx_mmu; + while ( (skb = skb_dequeue(&rx_queue)) != NULL ) { - netif = ((rx_info_t *)&skb->cb[0])->netif; + netif = (netif_t *)skb->dev->priv; vdata = (unsigned long)skb->data; mdata = virt_to_machine(vdata); new_mfn = get_new_mfn(); @@ -231,11 +224,9 @@ static void net_rx_action(unsigned long unused) mcl[1].args[1] = 3; mcl[1].args[2] = 0; - mmu += 3; mcl += 2; + mmu += 3; - ((rx_info_t *)&skb->cb[0])->old_mach_ptr = mdata; - ((rx_info_t *)&skb->cb[0])->new_mach_pfn = new_mfn; __skb_queue_tail(&rxq, skb); /* Filled the batch queue? */ @@ -250,14 +241,17 @@ static void net_rx_action(unsigned long unused) (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); mcl = rx_mcl; + mmu = rx_mmu; while ( (skb = __skb_dequeue(&rxq)) != NULL ) { - netif = ((rx_info_t *)&skb->cb[0])->netif; + netif = (netif_t *)skb->dev->priv; size = skb->tail - skb->data; - id = ((rx_info_t *)&skb->cb[0])->id; - new_mfn = ((rx_info_t *)&skb->cb[0])->new_mach_pfn; - mdata = ((rx_info_t *)&skb->cb[0])->old_mach_ptr; + /* Rederive the machine addresses. */ + new_mfn = mcl[0].args[1] >> PAGE_SHIFT; + mdata = ((mmu[2].ptr & PAGE_MASK) | + ((unsigned long)skb->data & ~PAGE_MASK)); + /* Check the reassignment error code. */ if ( unlikely(mcl[1].args[5] != 0) ) { @@ -285,6 +279,7 @@ static void net_rx_action(unsigned long unused) } evtchn = netif->evtchn; + id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id; if ( make_rx_response(netif, id, status, mdata, size) && (rx_notify[evtchn] == 0) ) { @@ -295,6 +290,7 @@ static void net_rx_action(unsigned long unused) dev_kfree_skb(skb); mcl += 2; + mmu += 3; } while ( notify_nr != 0 ) @@ -406,10 +402,11 @@ static void net_tx_action(unsigned long unused) { pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)]; - netif = pending_netif[pending_idx]; + netif = pending_tx_info[pending_idx].netif; spin_lock(&netif->tx_lock); - make_tx_response(netif, pending_id[pending_idx], NETIF_RSP_OKAY); + make_tx_response(netif, pending_tx_info[pending_idx].req.id, + NETIF_RSP_OKAY); spin_unlock(&netif->tx_lock); pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; @@ -512,10 +509,11 @@ static void net_tx_action(unsigned long unused) mcl[0].args[2] = 0; mcl[0].args[3] = netif->domid; mcl++; - - ((tx_info_t *)&skb->cb[0])->idx = pending_idx; - ((tx_info_t *)&skb->cb[0])->netif = netif; - memcpy(&((tx_info_t *)&skb->cb[0])->req, &txreq, sizeof(txreq)); + + memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq)); + pending_tx_info[pending_idx].netif = netif; + *((u16 *)skb->data) = pending_idx; + __skb_queue_tail(&tx_queue, skb); pending_cons++; @@ -533,9 +531,9 @@ static void net_tx_action(unsigned long unused) mcl = tx_mcl; while ( (skb = __skb_dequeue(&tx_queue)) != NULL ) { - pending_idx = ((tx_info_t *)&skb->cb[0])->idx; - netif = ((tx_info_t *)&skb->cb[0])->netif; - memcpy(&txreq, &((tx_info_t *)&skb->cb[0])->req, sizeof(txreq)); + pending_idx = *((u16 *)skb->data); + netif = pending_tx_info[pending_idx].netif; + memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq)); /* Check the remap error code. */ if ( unlikely(mcl[0].args[5] != 0) ) @@ -581,8 +579,6 @@ static void net_tx_action(unsigned long unused) */ page->mapping = (struct address_space *)netif_page_release; atomic_set(&page->count, 1); - pending_id[pending_idx] = txreq.id; - pending_netif[pending_idx] = netif; netif->stats.tx_bytes += txreq.size; netif->stats.tx_packets++; diff --git a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c index 25bad4b576..9074ad6ded 100644 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c @@ -99,8 +99,6 @@ static struct net_device *find_dev_by_handle(unsigned int handle) return NULL; } -#define MULTIVIF - /** Network interface info. */ struct netif_ctrl { /** Number of interfaces. */ @@ -385,14 +383,8 @@ static void netif_int(int irq, void *dev_id, struct pt_regs *ptregs) unsigned long flags; spin_lock_irqsave(&np->tx_lock, flags); - - if( !netif_carrier_ok(dev) ) - { - spin_unlock_irqrestore(&np->tx_lock, flags); - return; - } - - network_tx_buf_gc(dev); + if ( likely(netif_carrier_ok(dev)) ) + network_tx_buf_gc(dev); spin_unlock_irqrestore(&np->tx_lock, flags); if ( np->rx_resp_cons != np->rx->resp_prod ) @@ -414,7 +406,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) spin_lock(&np->rx_lock); - /* if the device is undergoing recovery then don't do anything */ + /* If the device is undergoing recovery then don't do anything. */ if ( !netif_carrier_ok(dev) ) { spin_unlock(&np->rx_lock); @@ -721,20 +713,17 @@ static void netif_status_change(netif_fe_interface_status_changed_t *status) memcpy(dev->dev_addr, status->mac, ETH_ALEN); - if(netif_carrier_ok(dev)){ + if ( netif_carrier_ok(dev) ) np->state = NETIF_STATE_CONNECTED; - } else { + else network_reconnect(dev, status); - } np->evtchn = status->evtchn; np->irq = bind_evtchn_to_irq(np->evtchn); (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, dev->name, dev); -#ifdef MULTIVIF netctrl_connected_count(); -#endif break; default: @@ -744,13 +733,13 @@ static void netif_status_change(netif_fe_interface_status_changed_t *status) } } -/** Create a network devices. - * +/** Create a network device. * @param handle device handle * @param val return parameter for created device * @return 0 on success, error code otherwise */ -static int create_netdev(int handle, struct net_device **val){ +static int create_netdev(int handle, struct net_device **val) +{ int err = 0; struct net_device *dev = NULL; struct net_private *np = NULL; @@ -847,11 +836,7 @@ static int __init init_module(void) { ctrl_msg_t cmsg; netif_fe_driver_status_changed_t st; - int err = 0; -#ifdef MULTIVIF - int wait_n = 20; - int wait_i; -#endif + int err = 0, wait_i, wait_n = 20; if ( (start_info.flags & SIF_INITDOMAIN) || (start_info.flags & SIF_NET_BE_DOMAIN) ) @@ -860,9 +845,8 @@ static int __init init_module(void) printk("Initialising Xen virtual ethernet frontend driver"); INIT_LIST_HEAD(&dev_list); -#ifdef MULTIVIF + netctrl_init(); -#endif (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx, CALLBACK_IN_BLOCKING_CONTEXT); @@ -876,7 +860,6 @@ static int __init init_module(void) memcpy(cmsg.msg, &st, sizeof(st)); ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); -#ifdef MULTIVIF /* Wait for all interfaces to be connected. */ for ( wait_i = 0; ; wait_i++) { @@ -888,7 +871,6 @@ static int __init init_module(void) set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); } -#endif if ( err ) ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx); -- 2.30.2